
// ImageCuratorGUI.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "afxwinappex.h"
#include "afxdialogex.h"
#include "ImageCuratorGUI.h"
#include "MainFrm.h"

#include "ChildFrm.h"
#include "ImageCuratorGUIDoc.h"
#include "ImageCuratorGUIView.h"
#include "ShowErrorDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CImageCuratorGUIApp

BEGIN_MESSAGE_MAP(CImageCuratorGUIApp, CWinAppEx)
	ON_COMMAND(ID_APP_ABOUT, &CImageCuratorGUIApp::OnAppAbout)
	// Standard file based document commands
	ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)
END_MESSAGE_MAP()


// CImageCuratorGUIApp construction

CImageCuratorGUIApp::CImageCuratorGUIApp() :
	_imagecurator(nullptr),
	_verInfo(nullptr),
	_mxPluginManager(nullptr)
{
	m_bHiColorIcons = TRUE;

	// support Restart Manager
	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;
#ifdef _MANAGED
	// If the application is built using Common Language Runtime support (/clr):
	//     1) This additional setting is needed for Restart Manager support to work properly.
	//     2) In your project, you must add a reference to System.Windows.Forms in order to build.
	System::Windows::Forms::Application::SetUnhandledExceptionMode(System::Windows::Forms::UnhandledExceptionMode::ThrowException);
#endif

	_verInfo = new MxVersionInfo();
	ASSERT( MxGUID::IsEqual(PRODID_ImageCuratorGUI, MxGUID::ConvertFromString(_verInfo->GetProductID()) ));
	MX_SETUP(MxGUID::ConvertFromString(_verInfo->GetProductID()), _verInfo->GetProductName(), _verInfo->GetVersion(), MxError::Development, MxError::VerboseReport, "App starts");

	CString ProdOwner(ProdIdImageCuratorGUI::Owner());
	CString ProdName(_verInfo->GetProductName());
	CString ProdVer(_verInfo->GetVersion());
	ProdVer.Replace('.', '-');
	CString AppId(L"");
	AppId.Format(L"%s.%s.%s",ProdOwner, ProdName, ProdVer);
	SetAppID(AppId);
}

CImageCuratorGUIApp::~CImageCuratorGUIApp()
{
	MX_END(MxError::VerboseReport, "App ends");

	if (_imagecurator != nullptr)
		delete _imagecurator;
	_imagecurator = nullptr;
	if (_mxPluginManager != nullptr)
		delete _mxPluginManager;
	_mxPluginManager = nullptr;
	if (_verInfo != nullptr)
		delete _verInfo;
	_verInfo = nullptr;

	//Bit of a cludge just to stop VS2012 reporting memory leaks before the following are called in their appropriate dtors
	//This memory is being freed, but not before VS2012 expects this to happen. Even if the memory was not freed would it matter, 
	//because it is freed when the process ends? The reason I'm doing this cludge is because lots of phantom errors may mask a 
	//real memory leak or other problem.

	ImageCurator::CleanupOnAppExitOnly();
	MxPluginManager::CleanupOnAppExitOnly();
	MxUtils::Inst().CleanupOnAppExitOnly();
	MxError::Inst().CleanupOnAppExitOnly();

	//cludge ends


}
// The one and only CImageCuratorGUIApp object

CImageCuratorGUIApp theApp;


// CImageCuratorGUIApp initialization

BOOL CImageCuratorGUIApp::InitInstance()
{
	BOOL rc = FALSE;
	// InitCommonControlsEx() is required on Windows XP if an application
	// manifest specifies use of ComCtl32.dll version 6 or later to enable
	// visual styles.  Otherwise, any window creation will fail.
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// Set this to include all the common control classes you want to use
	// in your application.
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinAppEx::InitInstance();


	// Initialize OLE libraries
	if (!AfxOleInit())
	{
		AfxMessageBox(IDP_OLE_INIT_FAILED);
		return FALSE;
	}

	AfxEnableControlContainer();

	EnableTaskbarInteraction();

	// AfxInitRichEdit2() is required to use RichEdit control	
	// AfxInitRichEdit2();


	// Standard initialization
	// If you are not using these features and wish to reduce the size
	// of your final executable, you should remove from the following
	// the specific initialization routines you do not need
	// Change the registry key under which our settings are stored
	// TODO: You should modify this string to be something appropriate
	// such as the name of your company or organization


	try
	{
		USES_CONVERSION;
		
		SetRegistryKey(A2CW(_verInfo->GetOwner()));

		bool DoResetFactoryDefaults = false;

		_mxPluginManager = new MxPluginManager(ProdIdMxPluginManagerGUI::Owner(), ProdIdMxPluginManagerGUI::Name(), ProdIdMxPluginManagerGUI::ProdID(), ProdIdMxPluginManagerGUI::SID());
		if (_mxPluginManager->GetAppIndex(ProdIdImageCuratorGUI::ProdID()) == MxPluginManager::InvalidVal )
			DoResetFactoryDefaults = true;

		if (_mxPluginManager->RegAppInit(_verInfo->GetProductName(), MxGUID::ConvertFromString(_verInfo->GetProductID()),  ProdIdImageCuratorGUI::SID(), MxError::Development, MxError::VerboseReport) == false)
			MX_SETERROR ( MX1602, MxError::System, MxError::Abort, MxError::QuietReport, "RegAppInit failed %s, %s", _verInfo->GetProductName(), _verInfo->GetProductID());
		else
		{
			MxError::Inst().SetLogging (_mxPluginManager->GetAppLogChannel(_verInfo->GetProductID()), _mxPluginManager->GetAppLogLevel(_verInfo->GetProductID()));

			_imagecurator = new ImageCurator();

			if (DoResetFactoryDefaults && (AfxMessageBox(IDS_SETFACTORYDEFAULTS_YESNO, MB_YESNO) == IDYES ))
				SetFactoryDefaults();
		
			LoadStdProfileSettings(4);  // Load standard INI file options (including MRU)

			InitContextMenuManager();

			InitKeyboardManager();

			InitTooltipManager();
			CMFCToolTipInfo ttParams;
			ttParams.m_bVislManagerTheme = TRUE;
			theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
				RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);

			// Register the application's document templates.  Document templates
			//  serve as the connection between documents, frame windows and views
			CMultiDocTemplate* pDocTemplate;
			pDocTemplate = new CMultiDocTemplate(IDR_ImageDatasetTYPE,
				RUNTIME_CLASS(CImageCuratorGUIDoc),
				RUNTIME_CLASS(CChildFrame), // custom MDI child frame
				RUNTIME_CLASS(CImageCuratorGUIView));
			if (!pDocTemplate)
				return FALSE;
			AddDocTemplate(pDocTemplate);

			// create main MDI Frame window
			CMainFrame* pMainFrame = new CMainFrame;
			if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
			{
				delete pMainFrame;
				return FALSE;
			}
			m_pMainWnd = pMainFrame;

			// call DragAcceptFiles only if there's a suffix
			//  In an MDI app, this should occur immediately after setting m_pMainWnd
			// Enable drag/drop open
			m_pMainWnd->DragAcceptFiles();

			// Parse command line for standard shell commands, DDE, file open
			CCommandLineInfo cmdInfo;
			ParseCommandLine(cmdInfo);

			// Enable DDE Execute open
			EnableShellOpen();
			RegisterShellFileTypes(TRUE);


			// Dispatch commands specified on the command line.  Will return FALSE if
			// app was launched with /RegServer, /Register, /Unregserver or /Unregister.
			if (!ProcessShellCommand(cmdInfo))
				return FALSE;
			// The main window has been initialized, so show and update it
			pMainFrame->ShowWindow(m_nCmdShow);
			pMainFrame->UpdateWindow();
		}
	}
	catch(std::exception const& e)
	{
		MX_SETERROR ( MX8001, MxError::System, MxError::TerminateApp, MxError::QuietReport, "unexpected exception - %s", e.what());
	}

	if ( MxError::Inst().IsErrorSet())
		ShowErrorDlg::DisplayUserError(IDS_BADACTION_INITAPP);
	else
		rc = TRUE;

	return rc;
}

int CImageCuratorGUIApp::ExitInstance()
{
	//TODO: handle additional resources you may have added
	AfxOleTerm(FALSE);

	return CWinAppEx::ExitInstance();
}

bool  CImageCuratorGUIApp::SetFactoryDefaults()
{
	bool rc = false;


	rc = true;

	return rc;
}
// CImageCuratorGUIApp message handlers


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// Dialog Data
	enum { IDD = IDD_ABOUTBOX };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
	DECLARE_MESSAGE_MAP()
public:
	CString m_ProductDescription;
	CString m_ProductCopyright;
	CString m_ProductSupportSite;
	CString m_ProductLicenseDetails;
	CString m_ProductVersion;
	CString m_Libraries;
	virtual BOOL OnInitDialog();
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
	, m_ProductDescription(_T(""))
	, m_ProductCopyright(_T(""))
	, m_ProductSupportSite(ProdIdImageCuratorGUI::SupportSite())
	, m_ProductLicenseDetails(ProdIdImageCuratorGUI::LicenceWebPage())
	, m_ProductVersion(_T(""))
	, m_Libraries(_T(""))
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_PRODUCTDESCRIPTION_STATIC, m_ProductDescription);
	DDX_Text(pDX, IDC_COPYRIGHTSTATIC, m_ProductCopyright);
	DDX_Text(pDX, IDC_IMAGECURATORSUPPORTSITELINK, m_ProductSupportSite);
	DDX_Text(pDX, IDC_IMAGECURATORLICENCELINK, m_ProductLicenseDetails);
	DDX_Text(pDX, IDC_VERSIONSTATIC, m_ProductVersion);
	DDX_Text(pDX, IDC_LIBLIST_EDIT, m_Libraries);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


BOOL CAboutDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	MxVersionInfo vers;
	m_ProductVersion = vers.GetVersion();
	m_ProductCopyright = vers.GetCopyrightNotice();
	m_ProductDescription = vers.GetDescription();

	CImageCuratorGUIApp *app = dynamic_cast<CImageCuratorGUIApp *>(AfxGetApp());
	if (app != nullptr)
	{
		m_Libraries = L"Loadtime:\r\n";
		m_Libraries += app->GetICLib()->GetLibName();
		m_Libraries += L" v";
		m_Libraries += app->GetICLib()->GetLibVersion();
		m_Libraries += L", ";
		m_Libraries += app->GetICLib()->GetLibCopyrightNotice();
		m_Libraries += L" License: ";
		m_Libraries += app->GetICLib()->GetLibLicenseURL();
		m_Libraries += L"\r\n\r\nRuntime:\r\n";
	}

	UpdateData(FALSE);

	return TRUE;  
}

// App command to run the dialog
void CImageCuratorGUIApp::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}

// CImageCuratorGUIApp customization load/save methods

void CImageCuratorGUIApp::PreLoadState()
{
	BOOL bNameValid;
	CString strName;
	bNameValid = strName.LoadString(IDS_EDIT_MENU);
	ASSERT(bNameValid);
	GetContextMenuManager()->AddMenu(strName, IDR_POPUP_EDIT);
}

void CImageCuratorGUIApp::LoadCustomState()
{
}

void CImageCuratorGUIApp::SaveCustomState()
{
}

// CImageCuratorGUIApp message handlers






